-- vim.keymap.set('n', '<leader>q', vim.diagnostic.open_float, { desc = 'open float diagnostic' })
vim.keymap.set('n', '[d', function()
  vim.diagnostic.jump { count = 1, float = true }
end, { desc = 'go to prev diagnostic' })
vim.keymap.set('n', ']d', function()
  vim.diagnostic.jump { count = -1, float = true }
end, { desc = 'go to next diagnostic' })
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'diagnostic set loclist' })
vim.keymap.set("x", "<leader>re", ":Refactor extract ")
vim.keymap.set("x", "<leader>rf", ":Refactor extract_to_file ")

vim.keymap.set("x", "<leader>rv", ":Refactor extract_var ")

vim.keymap.set({ "n", "x" }, "<leader>ri", ":Refactor inline_var")

vim.keymap.set("n", "<leader>rI", ":Refactor inline_func")

vim.keymap.set("n", "<leader>rb", ":Refactor extract_block")
vim.keymap.set("n", "<leader>rbf", ":Refactor extract_block_to_file")

vim.keymap.set("x", "<leader>rr", function() require('refactoring').select_refactor { show_success_message = true } end,
  { desc = 'refactor' })
vim.keymap.set("x", "<leader>re", function() require('refactoring').refactor('Extract Function') end,
  { desc = 'refactor extract function' })
vim.keymap.set("x", "<leader>rf", function() require('refactoring').refactor('Extract Function To File') end,
  { desc = 'refactor extract function to file' })
-- Extract function supports only visual mode
vim.keymap.set("x", "<leader>rv", function() require('refactoring').refactor('Extract Variable') end,
  { desc = 'refactor extract variable' })
-- Extract variable supports only visual mode
vim.keymap.set("n", "<leader>rI", function() require('refactoring').refactor('Inline Function') end,
  { desc = 'refactor inline function' })
-- Inline func supports only normal
vim.keymap.set({ "n", "x" }, "<leader>ri", function() require('refactoring').refactor('Inline Variable') end,
  { desc = 'refactor inline variable' })
-- Inline var supports both normal and visual mode

vim.keymap.set("n", "<leader>rb", function() require('refactoring').refactor('Extract Block') end,
  { desc = 'extract block' })
vim.keymap.set("n", "<leader>rbf", function() require('refactoring').refactor('Extract Block To File') end,
  { desc = 'extract block to file' })


vim.keymap.set("n", "<leader>rn", function()
  return ":IncRename " .. vim.fn.expand("<cword>")
end, { expr = true, desc = 'rename symbol' })


vim.api.nvim_create_autocmd('LspAttach', {
  group = vim.api.nvim_create_augroup('UserLspConfig', {}),
  callback = function(ev)
    -- Enable completion triggered by <c-x><c-o>
    vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'

    local opts = { buffer = ev.buf }
    vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, vim.tbl_extend('force', opts, { desc = 'go to declaration' }))
    vim.keymap.set('n', 'gd', vim.lsp.buf.definition, vim.tbl_extend('force', opts, { desc = 'go to definition' }))
    vim.keymap.set('n', '<C-k>', vim.lsp.buf.hover, vim.tbl_extend('force', opts, { desc = 'hover' }))
    vim.keymap.set('n', 'gi', vim.lsp.buf.implementation,
      vim.tbl_extend('force', opts, { desc = 'go to implementation' }))
    vim.keymap.set('n', '<leader>wa', vim.lsp.buf.add_workspace_folder,
      vim.tbl_extend('force', opts, { desc = 'add workspace folder' }))
    vim.keymap.set('n', '<leader>wr', vim.lsp.buf.remove_workspace_folder,
      vim.tbl_extend('force', opts, { desc = 'remove workspace folder' }))
    vim.keymap.set('n', '<leader>wl', function()
      print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
    end, vim.tbl_extend('force', opts, { desc = 'list workspace folder' }))
    vim.keymap.set('n', '<leader>D', vim.lsp.buf.type_definition,
      vim.tbl_extend('force', opts, { desc = 'go to type definition' }))
    -- vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename, vim.tbl_extend('force', opts, { desc = 'rename symbol' }))
    vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action,
      vim.tbl_extend('force', opts, { desc = 'code action' }))
    vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
  end,
})


return {
  {

    "williamboman/mason.nvim",
    config = true,
  },
  {
    "neovim/nvim-lspconfig",
    event = 'VimEnter',
    config = function()
      local capabilities = require("cmp_nvim_lsp").default_capabilities()


      local lspconfig = require "lspconfig"
      local icons = require "next.utils.icon"

      vim.diagnostic.config {
        underline = true,
        update_in_insert = false,
        virtual_text = {
          spacing = 4,
          source = "if_many",
          prefix = "●",
          -- this will set set the prefix to a function that returns the diagnostics icon based on the severity
          -- this only works on a recent 0.10.0 build. Will be set to "●" when not supported
          -- prefix = "icons",
        },
        severity_sort = true,
        signs = {
          text = {
            [vim.diagnostic.severity.ERROR] = icons.diagnostics.Error,
            [vim.diagnostic.severity.WARN] = icons.diagnostics.Warn,
            [vim.diagnostic.severity.HINT] = icons.diagnostics.Hint,
            [vim.diagnostic.severity.INFO] = icons.diagnostics.Info,
          },
        },
      }
      local servers = { "tsserver", "vuels", "html", "cssls", "jsonls", "bashls", "clangd" }

      for _, server in ipairs(servers) do
        lspconfig[server].setup {
          capabilities = capabilities,
        }
      end

      lspconfig.lua_ls.setup {
        capabilities = capabilities,
        settings = {
          Lua = {
            diagnostics = {
              globals = { "vim" },
            },
            workspace = {
              library = {
                [vim.fn.expand "$VIMRUNTIME/lua"] = true,
                [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true,
                [require('next.config').plugins.install_path .. "Lazy.nvim/lua"] = true,
              },
              maxPreload = 100000,
              preloadFileSize = 10000,
            },
          },
        },
      }
      -- lspconfig.rust_analyzer.setup {
      --   -- Server-specific settings. See `:help lspconfig-setup`
      --   settings = {
      --     ["rust-analyzer"] = {},
      --   },
      -- }
    end,
  },

  {
    "glepnir/lspsaga.nvim",
    opts = {},
  },
  {
    "smjonas/inc-rename.nvim",
    opts = {
      post_hook = function()
        vim.cmd "wa"
      end,
    },
  },
  { "folke/neodev.nvim",    opts = {} },
  {
    "folke/lazydev.nvim",
    ft = "lua", -- only load on lua files
    opts = {
      library = {

        require('next.config').plugins.install_path .. "Lazy.nvim/lua",
        -- See the configuration section for more details
        -- Load luvit types when the `vim.uv` word is found
        { path = "luvit-meta/library", words = { "vim%.uv" } },
        "lazy.nvim",
        "LazyVim",
      },
    },
  },
  { "Bilal2453/luvit-meta", lazy = true }, -- optional `vim.uv` typings
  {
    "nvimtools/none-ls.nvim",
    opts = {},
  },
}
